package com.hy.medicine.vo;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;

@Data
public class MedicineImportTemplate {
    @ExcelProperty(value = "药品名称*", index = 0)
    @NotBlank(message = "药品名称不能为空")
    private String medicineName;

    @ExcelProperty(value = "批准文号*", index = 1)
    @NotBlank(message = "批准文号不能为空")
    private String approvalNumber;

    @ExcelProperty(value = "规格*", index = 2)
    @NotBlank(message = "规格不能为空")
    private String specification;

    @ExcelProperty(value = "剂型*", index = 3)
    @NotBlank(message = "剂型不能为空")
    private String dosageForm;

    @ExcelProperty(value = "生产厂家*", index = 4)
    @NotBlank(message = "生产厂家不能为空")
    private String manufacturer;

    @ExcelProperty(value = "保质期(月)*", index = 5)
    @NotNull(message = "保质期不能为空")
    @Min(value = 1, message = "保质期必须大于0个月")
    private Integer shelfLife;

    @ExcelProperty(value = "储存条件*", index = 6)
    @NotBlank(message = "储存条件不能为空")
    private String storageCondition;

    @ExcelProperty(value = "单价(元)*", index = 7, converter = PriceConverter.class)
    @NumberFormat("#,##0.00")
    @NotNull(message = "单价不能为空")
    @DecimalMin(value = "0.01", message = "单价必须大于0")
    private BigDecimal price;

    @ExcelProperty(value = "库存数量*", index = 8)
    @NotNull(message = "库存数量不能为空")
    @Min(value = 0, message = "库存数量不能小于0")
    private Integer minStock;

    @ExcelProperty(value = "通用分类ID*", index = 9)
    @NotBlank(message = "通用分类不能为空")
    private String commonCategoryId;

    @ExcelProperty(value = "处方分类ID*", index = 10)
    @NotBlank(message = "处方类型不能为空")
    private String prescriptionCategoryId;

    /**
     * 价格转换器
     */
    public static class PriceConverter implements Converter<BigDecimal> {
        private static final int DECIMAL_PLACES = 2;
        private static final String PRICE_ERROR = "单价格式不正确，请输入有效的数字，最多支持2位小数";
        private static final BigDecimal MAX_PRICE = new BigDecimal("999999.99");
        private static final BigDecimal MIN_PRICE = new BigDecimal("0.01");

        @Override
        public Class<BigDecimal> supportJavaTypeKey() {
            return BigDecimal.class;
        }

        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return null; // 支持所有类型
        }

        @Override
        public BigDecimal convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
                                          GlobalConfiguration globalConfiguration) {
            try {
                BigDecimal price = null;

                switch (cellData.getType()) {
                    case NUMBER:
                        price = convertNumberCell(cellData);
                        break;
                    case STRING:
                        price = convertStringCell(cellData);
                        break;
                    case EMPTY:
                        return null;
                    default:
                        throw new IllegalArgumentException(PRICE_ERROR);
                }

                // 验证价格范围
                validatePrice(price);

                // 设置精度
                return price.setScale(DECIMAL_PLACES, RoundingMode.HALF_UP);
            } catch (Exception e) {
                throw new IllegalArgumentException(PRICE_ERROR);
            }
        }

        private BigDecimal convertNumberCell(ReadCellData<?> cellData) {
            BigDecimal value = cellData.getNumberValue();
            if (value == null) {
                throw new IllegalArgumentException(PRICE_ERROR);
            }
            return value;
        }

        private BigDecimal convertStringCell(ReadCellData<?> cellData) {
            String value = cellData.getStringValue();
            if (StringUtils.isBlank(value)) {
                return null;
            }
            // 清理字符串中的无效字符
            value = value.replaceAll("[^\\d.-]", "").trim();
            if (StringUtils.isBlank(value)) {
                throw new IllegalArgumentException(PRICE_ERROR);
            }
            return new BigDecimal(value);
        }

        private void validatePrice(BigDecimal price) {
            if (price == null) {
                throw new IllegalArgumentException("单价不能为空");
            }
            if (price.compareTo(MIN_PRICE) < 0) {
                throw new IllegalArgumentException("单价不能小于0.01元");
            }
            if (price.compareTo(MAX_PRICE) > 0) {
                throw new IllegalArgumentException("单价不能超过999999.99元");
            }
            // 检查小数位数
            if (price.scale() > DECIMAL_PLACES) {
                throw new IllegalArgumentException("单价最多支持2位小数");
            }
        }

        @Override
        public WriteCellData<?> convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty,
                                                  GlobalConfiguration globalConfiguration) {
            if (value == null) {
                return new WriteCellData<>("");
            }
            // 导出时格式化为标准金额格式
            String formattedValue = String.format("%,.2f", value);
            return new WriteCellData<>(formattedValue);
        }
    }
}
